// DriveNotes. Copyright (c) 2011, Andrei Senchuk. All rights reserved.
package net.taviscaron.drivenotes.web.action;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.taviscaron.drivenotes.shared.exceptions.InvalidEntityException;
import net.taviscaron.drivenotes.shared.model.entity.Car;
import net.taviscaron.drivenotes.shared.model.entity.User;
import net.taviscaron.drivenotes.shared.service.GarageService;
import net.taviscaron.drivenotes.web.converter.FormConverter;
import net.taviscaron.drivenotes.web.converter.InvalidFormException;
import net.taviscaron.drivenotes.web.forward.ActionRedirect;
import net.taviscaron.drivenotes.web.core.Constants;
import net.taviscaron.drivenotes.web.forward.RequestForwarder;
import net.taviscaron.drivenotes.web.forward.ViewForward;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;

/**
 * Car edit action (binded to (editCar and newCar) actions
 * @author Andrei Senchuk
 */
public class CarEditAction implements Action {
    public enum Error {
        BAD_PARAMS;
    }

    private static final Log logger = LogFactory.getLog(CarEditAction.class);
    private GarageService garageService;
    private FormConverter<Car> carConverter;

    @Required
    public void setCarConverter(FormConverter<Car> carConverter) {
        this.carConverter = carConverter;
    }

    @Required
    public void setGarageService(GarageService garageService) {
        this.garageService = garageService;
    }

    public RequestForwarder doAction(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String subaction = request.getParameter(Constants.SUBACTION_PARAM_NAME);

        if(subaction == null) {
            return newEditAction(request, response);
        } else if ("save".equals(subaction)) {
            return saveAction(request, response);
        } else if ("del".equals(subaction)) {
            return deleteAction(request, response);
        } else {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "bad subaction");
            return null;
        }
    }

    private RequestForwarder deleteAction(HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = (User)request.getAttribute(Constants.AUTHORIZED_USER_ATTR_NAME);
        Long id = null;
        try {
            id = Long.valueOf(request.getParameter("id"));

            Car original = garageService.findCar(id, user);
            if(original == null) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return null;
            }

            garageService.removeCarById(id);
            return new ActionRedirect("garage");
        } catch (NumberFormatException e) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
        }
        return null;
    }

    private RequestForwarder saveAction(HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = (User)request.getAttribute(Constants.AUTHORIZED_USER_ATTR_NAME);
        Car car = null;
        try {
            car = carConverter.convert(request.getParameterMap());
            car.setOwner(user);
            if(car.getId() != null) {
                Car original = garageService.findCar(car.getId(), user);
                if(original == null) {
                    response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                    return null;
                }
            }

            garageService.saveCar(car);
            return new ActionRedirect("garage");
        } catch(InvalidFormException e) {
            request.setAttribute("error", Error.BAD_PARAMS);
            logger.debug("user is trying to save invalid car: [" + car + "]", e);
            return new ViewForward("carEdit");
        } catch(InvalidEntityException e) {
            request.setAttribute("error", e.getReason());
            return new ViewForward("carEdit");
        }
    }

    private RequestForwarder newEditAction(HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = (User)request.getAttribute(Constants.AUTHORIZED_USER_ATTR_NAME);
        if (request.getParameter("id") != null) {
            Long id = null;
            try {
                id = Long.valueOf(request.getParameter("id"));
            } catch (NumberFormatException e) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return null;
            }
            Car car = garageService.findCar(id, user);
            request.setAttribute("car", car);
        }
        return new ViewForward("carEdit");
    }
}
